home *** CD-ROM | disk | FTP | other *** search
/ MacHack 2000 / MacHack 2000.toast / pc / The Hacks / MacHacksBug / Python 1.5.2c1 / Extensions / Imaging / PIL / FontFile.py < prev    next >
Encoding:
Python Source  |  2000-06-23  |  3.2 KB  |  144 lines

  1. #
  2. # THIS IS WORK IN PROGRESS
  3. #
  4. # The Python Imaging Library
  5. # $Id: FontFile.py,v 1.1.1.2 1999/01/13 09:40:08 sjoerd Exp $
  6. #
  7. # base class for raster font file parsers
  8. #
  9. # history:
  10. # 97-06-05 fl   created
  11. # 97-08-19 fl   restrict image width
  12. #
  13. # Copyright (c) Secret Labs AB 1997-98.
  14. # Copyright (c) Fredrik Lundh 1997.
  15. #
  16. # See the README file for information on usage and redistribution.
  17. #
  18.  
  19. import os
  20. import Image
  21.  
  22. import marshal
  23.  
  24. try:
  25.     import zlib
  26. except ImportError:
  27.     zlib = None
  28.  
  29. WIDTH = 800
  30.  
  31. def puti16(fp, values):
  32.     # write network order (big-endian) 16-bit sequence
  33.     for v in values:
  34.         if v < 0:
  35.             v = v + 65536
  36.     fp.write(chr(v>>8&255) + chr(v&255))
  37.  
  38. class FontFile:
  39.  
  40.     bitmap = None
  41.  
  42.     def __init__(self):
  43.  
  44.         self.info = {}
  45.         self.glyph = [None] * 256
  46.  
  47.     def __getitem__(self, ix):
  48.         return self.glyph[ix]
  49.  
  50.     def compile(self):
  51.         "Create metrics and bitmap"
  52.  
  53.         if self.bitmap:
  54.             return
  55.  
  56.         # create bitmap large enough to hold all data
  57.         h = w = maxwidth = 0
  58.         lines = 1
  59.         for glyph in self:
  60.             if glyph:
  61.                 d, dst, src, im = glyph
  62.                 h = max(h, src[3] - src[1])
  63.                 w = w + (src[2] - src[0])
  64.                 if w > WIDTH:
  65.                     lines = lines + 1
  66.                     w = (src[2] - src[0])
  67.                 maxwidth = max(maxwidth, w)
  68.  
  69.         xsize = maxwidth
  70.         ysize = lines * h
  71.  
  72.         if xsize == 0 and ysize == 0:
  73.             return ""
  74.  
  75.         self.ysize = h
  76.  
  77.         # paste glyphs into bitmap
  78.         self.bitmap = Image.new("1", (xsize, ysize))
  79.         self.metrics = [None] * 256
  80.         x = y = 0
  81.         for i in range(256):
  82.             glyph = self[i]
  83.             if glyph:
  84.                 d, dst, src, im = glyph
  85.                 xx, yy = src[2] - src[0], src[3] - src[1]
  86.                 x0, y0 = x, y
  87.                 x = x + xx
  88.                 if x > WIDTH:
  89.                     x, y = 0, y + h
  90.                     x0, y0 = x, y
  91.                     x = xx
  92.                 s = src[0] + x0, src[1] + y0, src[2] + x0, src[3] + y0
  93.                 self.bitmap.paste(im.crop(src), s)
  94.                 # print chr(i), dst, s
  95.                 self.metrics[i] = d, dst, s
  96.  
  97.  
  98.     def save1(self, filename):
  99.         "Save font in version 1 format"
  100.  
  101.         self.compile()
  102.  
  103.         # font data
  104.         self.bitmap.save(os.path.splitext(filename)[0] + ".pbm", "PNG")
  105.  
  106.         # font metrics
  107.     fp = open(os.path.splitext(filename)[0] + ".pil", "wb")
  108.     fp.write("PILfont\n")
  109.     fp.write(";;;;;;%d;\n" % self.ysize) # HACK!!!
  110.     fp.write("DATA\n")
  111.     for id in range(256):
  112.         m = self.metrics[id]
  113.             if not m:
  114.         puti16(fp, [0] * 10)
  115.             else:
  116.         puti16(fp, m[0] + m[1] + m[2])
  117.     fp.close()
  118.  
  119.  
  120.     def save2(self, filename):
  121.         "Save font in version 2 format"
  122.  
  123.         self.compile()
  124.  
  125.         data = marshal.dumps((self.metrics, self.info))
  126.  
  127.         if zlib:
  128.             data = "z" + zlib.compress(data, 9)
  129.         else:
  130.             data = "u" + data
  131.  
  132.     fp = open(os.path.splitext(filename)[0] + ".pil", "wb")
  133.  
  134.         fp.write("PILfont2\n" + self.name + "\n" + "DATA\n")
  135.  
  136.         fp.write(data)
  137.  
  138.         self.bitmap.save(fp, "PNG")
  139.  
  140.         fp.close()
  141.  
  142.  
  143.     save = save1 # for now
  144.